package com.whtq.front.common.socket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class DefaultSocket {
    private static final Logger logger = LoggerFactory.getLogger(DefaultSocket.class);
    private Socket socket = null;
    protected OutputStream outputStream = null;
    protected InputStream inputStream = null;

    public DefaultSocket(String ip, int port) throws IOException {
       socket = new Socket(ip, port);
        socket.setSoTimeout(10000);
        outputStream = socket.getOutputStream();
        inputStream = socket.getInputStream();
    }

    public byte[] sendAndRead(byte[] msg) throws IOException {
        boolean sendFlag = send(msg);
        if(!sendFlag){
            throw new IOException("send failed. msg.length="+msg.length);
        }else{
            return read();
        }
    }

    public boolean send(byte[] msg) throws IOException {
        logger.info("send value={}", msg);
        try {
            outputStream.write(encode(msg));
            outputStream.flush();
            return true;
        } catch (Exception e) {
            logger.error("", e);
            close();
            throw e;
        }
    }

    public byte[] read() throws IOException {
        try {
            return decode(inputStream);
        } catch (Exception e) {
            logger.error("", e);
            close();
            throw e;
        }
    }

    public void close(){
        if(outputStream!=null){
            try {
                outputStream.close();
            } catch (IOException e) {
                logger.error("", e);
            } 
        }
        if(inputStream!=null){
            try {
                inputStream.close();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                logger.error("", e);
            }
        }
    }

    public byte[] encode(byte[] msg) {
        byte[] head = int2byte(msg.length);
        byte[] message = new byte[head.length+msg.length];
        System.arraycopy(head, 0, message, 0, 4);
        System.arraycopy(msg, 0, message, 4, msg.length);
        return message;
    }

    public byte[] int2byte(int i){
        byte[] ret = new byte[4];
        ret[0] = (byte) (i>>24);
        ret[1] = (byte) (i>>16);
        ret[2] = (byte) (i>>8);
        ret[3] = (byte) (i);
        return ret;
    }

    public byte[] decode(InputStream inputStream) throws IOException{
        byte[] head = new byte[4];
        int packetLength = -1;
        try {
            packetLength = inputStream.read(head);
            if (packetLength != head.length) {
                logger.error("读取错误：packetLength={}", packetLength);
                throw new IOException("读取包长度错误!");
            }
            packetLength = byte2int(head);
            byte[] packet = new byte[packetLength];
            inputStream.read(packet);
            logger.info("receive: msgLength={}", packetLength);
            return packet;
        } catch (IOException e) {
            logger.error("", e);
            throw e;
        }
    }

    private int byte2int(byte[] b) {
        return (((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) | ((b[2] & 0xff) << 8) | (b[3] & 0xff));
    }
}
